/**
 * Created : Mar 26, 2012
 *
 * @author pquiring
 */

import java.io.*;
import java.net.*;
import java.util.*;
import javaforce.*;

public class MainPanel extends javax.swing.JPanel {

  /**
   * Creates new form MainPanel
   */
  public MainPanel() {
    initComponents();
    configFile = JF.getUserPath() + "/.jfremote.xml";
    loadConfig();
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        protocol = new javax.swing.JComboBox();
        computer = new javax.swing.JComboBox();
        tabs = new javax.swing.JTabbedPane();
        jPanel2 = new javax.swing.JPanel();
        shareHome = new javax.swing.JCheckBox();
        consoleSession = new javax.swing.JCheckBox();
        jPanel1 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        port = new javax.swing.JTextField();
        connect = new javax.swing.JButton();
        clear = new javax.swing.JButton();

        jLabel1.setText("Computer:");

        jLabel2.setText("Protocol:");

        protocol.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "RDP", "VNC" }));
        protocol.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                protocolItemStateChanged(evt);
            }
        });

        computer.setEditable(true);
        computer.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                computerItemStateChanged(evt);
            }
        });

        shareHome.setSelected(true);
        shareHome.setText("Share Home Folder");

        consoleSession.setText("Connect to Console Session");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(shareHome, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(consoleSession, javax.swing.GroupLayout.DEFAULT_SIZE, 450, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(shareHome)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(consoleSession)
                .addContainerGap(34, Short.MAX_VALUE))
        );

        tabs.addTab("RDP", jPanel2);

        jLabel3.setText("Port:");

        port.setText("0");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(port, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(port, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(60, Short.MAX_VALUE))
        );

        tabs.addTab("VNC", jPanel1);

        connect.setText("Connect");
        connect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                connectActionPerformed(evt);
            }
        });

        clear.setText("Clear");
        clear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(protocol, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(computer, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addComponent(tabs, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(clear)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(connect)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(computer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(protocol, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tabs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(connect)
                    .addComponent(clear))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

  private void protocolItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_protocolItemStateChanged
    tabs.setSelectedIndex(protocol.getSelectedIndex());
  }//GEN-LAST:event_protocolItemStateChanged

  private void connectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectActionPerformed
    String host = (String)computer.getSelectedItem();
    if (host.length() == 0) return;
    try {
      InetAddress ip = InetAddress.getByName(host);
    } catch (Exception e) {
      JFAWT.showError("Error", "That host doesn't exist");
      return;
    }
    addHost();
    saveConfig();
    switch (protocol.getSelectedIndex()) {
      case 0: connectRDP(); break;
      case 1: connectVNC(); break;
    }
    System.exit(0);
  }//GEN-LAST:event_connectActionPerformed

  private void computerItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_computerItemStateChanged
    if (loading) return;
    int idx = computer.getSelectedIndex();
    if (idx == -1) return;
    port.setText("" + config.connection[idx].port);
    protocol.setSelectedItem(config.connection[idx].protocol);
    shareHome.setSelected(config.connection[idx].shareHome);
    consoleSession.setSelected(config.connection[idx].consoleSession);
  }//GEN-LAST:event_computerItemStateChanged

  private void clearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearActionPerformed
    computer.setSelectedItem("");
    protocol.setSelectedIndex(0);
    port.setText("0");
    shareHome.setSelected(true);
    consoleSession.setSelected(false);
  }//GEN-LAST:event_clearActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton clear;
    private javax.swing.JComboBox computer;
    private javax.swing.JButton connect;
    private javax.swing.JCheckBox consoleSession;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JTextField port;
    private javax.swing.JComboBox protocol;
    private javax.swing.JCheckBox shareHome;
    private javax.swing.JTabbedPane tabs;
    // End of variables declaration//GEN-END:variables

  public static class Connection {
    public String host, protocol;
    public int port;
    public boolean shareHome, consoleSession;
  }

  public static class Config {
    public Connection connection[];
  }

  private Config config;
  private String configFile;
  private boolean loading = true;

  private void connectRDP() {
    ArrayList<String> cmd = new ArrayList<String>();
    try {
      cmd.add("rdesktop");
      if (shareHome.isSelected()) {
        cmd.add("-r");
        cmd.add("disk:linux=" + JF.getUserPath());
      }
      if (consoleSession.isSelected()) cmd.add("-0");
      cmd.add((String)computer.getSelectedItem());
      Runtime.getRuntime().exec(cmd.toArray(new String[0]));
    } catch (Exception e) {
      JFAWT.showError("Error", "Failed to execute rdesktop");
    }
  }

  private void connectVNC() {
    String host = (String)computer.getSelectedItem();
    String p = port.getText();
    if (!p.equals("0")) host += ":" + p;
    try {
      String cmd[] = {"jvnc", host};
      Runtime.getRuntime().exec(cmd);
    } catch (Exception e) {
      JFAWT.showError("Error", "Failed to execute jvnc");
    }
  }

  private void loadConfig() {
    config = new Config();
    config.connection = null;
    try {
      XML xml = new XML();
      FileInputStream fis = new FileInputStream(configFile);
      xml.read(fis);
      xml.writeClass(config);
      for(int a=0;a<config.connection.length;a++) {
        computer.addItem(config.connection[a].host);
      }
      fis.close();
    } catch (Exception e) {
      config = new Config();
      config.connection = new Connection[0];
    }
    computer.setSelectedItem("");
    loading = false;
  }

  private void saveConfig() {
    try {
      XML xml = new XML();
      FileOutputStream fos = new FileOutputStream(configFile);
      xml.readClass("jfremote", config);
      xml.write(fos);
      fos.close();
    } catch (Exception e) {
    }
  }

  private void addHost() {
    String host = (String)computer.getSelectedItem();
    for(int a=0;a<config.connection.length;a++) {
      if (config.connection[a].host.equalsIgnoreCase(host)) {
        //update entry
        config.connection[a].port = JF.atoi(port.getText());
        config.connection[a].protocol = (String)protocol.getSelectedItem();
        config.connection[a].shareHome = shareHome.isSelected();
        config.connection[a].consoleSession = consoleSession.isSelected();
        return;
      }
    }
    //create new entry
    Connection newList[] = new Connection[config.connection.length + 1];
    System.arraycopy(config.connection, 0, newList, 0, config.connection.length);
    config.connection = newList;
    int idx = config.connection.length - 1;
    config.connection[idx] = new Connection();
    config.connection[idx].host = host;
    config.connection[idx].port = JF.atoi(port.getText());
    config.connection[idx].protocol = (String)protocol.getSelectedItem();
    config.connection[idx].shareHome = shareHome.isSelected();
    config.connection[idx].consoleSession = consoleSession.isSelected();
  }
}
